1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"824.48">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #007300}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0000bf}
19 span
.s1
{color: #0000bf}
20 span
.s2
{color: #007300}
21 span
.s3
{color: #000000}
22 span
.s4
{text-decoration: underline
; color: #0000bf}
23 span
.s5
{color: #bf0000}
24 span
.s6
{font: 12.0px Helvetica
}
25 span
.Apple-tab-span
{white-space:pre
}
29 <p class=
"p1"><b>Time-based patterns
</b></p>
30 <p class=
"p2"><br></p>
31 <p class=
"p3">"Time-based patterns" here are value patterns that use time as part of their calculation. Event patterns are naturally time-driven when played on a clock. (Technically it's possible to request events from an event stream without running it in an EventStreamPlayer, but this is not typical usage.)
</p>
32 <p class=
"p2"><br></p>
33 <p class=
"p3">Most of these patterns work by remembering the clock's current time at the moment the pattern is embedded into a value stream. The time value used for calculation is, then, the clock's time at the moment of evaluation minus the starting time -- that is, the number of beats elapsed since the patterns started embedding. If the pattern is embedded several times, the starting time is also reset so that the pattern begins again from the beginning.
</p>
34 <p class=
"p2"><br></p>
35 <p class=
"p3">There is nothing to prevent using these patterns outside of a scheduling context. In these documents, that context would be an event pattern played on a clock, but streams made from these patterns can be used in scheduled routines or functions as well. Only a scheduling context can ensure precise timing of requests for values.
</p>
36 <p class=
"p2"><br></p>
38 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Ptime(repeats):
</b> Returns the amount of time elapsed since embedding. One nice trick with this pattern is to stop a value stream/pattern after a certain amount of time.
</li>
40 <p class=
"p2"><br></p>
41 <p class=
"p3">This
<a href=
"../Patterns/Pif.html"><span class=
"s1">Pif
</span></a> pattern uses Ptime to get values from the true branch for exactly
4 beats after the first value is requested. After that, the condition will be false and Pif reverts to the false branch, which is nil. That causes the stream to stop. (This is like
<a href=
"../Patterns/Pfindur.html"><span class=
"s1">Pfindur
</span></a> for event patterns, but Pif/Ptime works for value patterns as well.)
</p>
42 <p class=
"p2"><br></p>
43 <p class=
"p4">// This is a really useful trick: like Pfindur but for value patterns
</p>
45 <p class=
"p5">p =
<span class=
"s1">Pbind
</span>(
</p>
46 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\degree
</span>,
<span class=
"s1">Pif
</span>(
<span class=
"s1">Ptime
</span>(
<span class=
"s1">inf
</span>)
< 4.0,
<span class=
"s1">Pwhite
</span>(-
4,
11,
<span class=
"s1">inf
</span>)),
</p>
47 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\dur
</span>,
0.25</p>
48 <p class=
"p5">).play;
</p>
50 <p class=
"p2"><br></p>
52 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pstep(levels, durs, repeats):
</b> Repeat a 'level' value for its corresponding duration, then move to the next.
</li>
53 <li style=
"margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pseg(levels, durs, curves, repeats):
</b> Similar to Pstep, but interpolates to the next value instead of stepping abruptly at the end of the duration. Interpolation is linear by default, but any envelope segment curve can be used. Levels, durs and curves should be patterns.
</li>
55 <p class=
"p2"><br></p>
56 <p class=
"p4">// curve is
5 - here's what the curve looks like, ascending first then descending
</p>
57 <p class=
"p5"><span class=
"s1">Env
</span>(#[
0,
1,
0], #[
1,
1],
5).plot;
</p>
58 <p class=
"p6"><br></p>
60 <p class=
"p5">p =
<span class=
"s1">Pbind
</span>(
</p>
61 <p class=
"p4"><span class=
"s3"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// using \note b/c Pseg will give fractional note numbers
</p>
62 <p class=
"p4"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>// can't use \degree because it handles non-integers differently
</p>
63 <p class=
"p7"><span class=
"s3"><span class=
"Apple-tab-span"> </span></span>\note
<span class=
"s3">,
</span><span class=
"s1">Pseg
</span><span class=
"s3">(
</span></p>
64 <p class=
"p4"><span class=
"s3"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span><span class=
"s1">Pwhite
</span><span class=
"s3">(-
7,
19,
</span><span class=
"s1">inf
</span><span class=
"s3">),
<span class=
"Apple-tab-span"> </span></span>// chromatic note numbers
</p>
65 <p class=
"p4"><span class=
"s3"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// alternate version for diatonic numbers
</p>
66 <p class=
"p4"><span class=
"s3"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// PdegreeToKey does the same conversion as \degree --
> \note
</p>
67 <p class=
"p4">//
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>PdegreeToKey(Pwhite(-
4,
11, inf), Pkey(\scale),
12),
</p>
68 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pwhite
</span>(
1,
4,
<span class=
"s1">inf
</span>) *
0.5,
</p>
69 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>5,
<span class=
"s1">inf
</span>),
</p>
70 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\dur
</span>,
0.125</p>
71 <p class=
"p5">).play;
</p>
73 <p class=
"p6"><br></p>
74 <p class=
"p5">p.stop;
</p>
75 <p class=
"p2"><br></p>
76 <p class=
"p2"><br></p>
77 <p class=
"p8"><b>Using envelopes as patterns
</b></p>
78 <p class=
"p2"><br></p>
79 <p class=
"p3"><span class=
"s4"><a href=
"../../Control/Env.html">Env
</a></span> supports the stream protocol: 'asStream' turns an Env into a stream, and timed values can be obtained from it using 'next'. The envelope stream returns the value the envelope would have at the elapsed time, in the same way .at(time) returns the envelope value at the specified time.
</p>
80 <p class=
"p2"><br></p>
81 <p class=
"p5">e =
<span class=
"s1">Env
</span>.linen(
1,
1,
1);
</p>
82 <p class=
"p5">e.at(
2);
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s5">// ==
1</span></p>
83 <p class=
"p5">e.at(
2.5);
<span class=
"Apple-tab-span"> </span><span class=
"s5">// ==
0.5</span></p>
84 <p class=
"p6"><br></p>
85 <p class=
"p4">// print envelope values
</p>
86 <p class=
"p5">r = fork {
</p>
87 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span><span class=
"Apple-tab-span"> </span>stream = e.asStream;
</p>
88 <p class=
"p5"><span class=
"Apple-tab-span"> </span>12.do({
</p>
89 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>stream.next.postln;
</p>
90 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>0.25.wait;
</p>
91 <p class=
"p5"><span class=
"Apple-tab-span"> </span>});
</p>
93 <p class=
"p6"><br></p>
94 <p class=
"p4">// Use an envelope to pan notes from left to right and back
</p>
95 <p class=
"p5">p =
<span class=
"s1">Pbind
</span>(
</p>
96 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\degree
</span>,
<span class=
"s1">Pwhite
</span>(-
4,
11,
32),
</p>
97 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\pan
</span>,
<span class=
"s1">Env
</span>(#[-
1,
1, -
1], #[
2,
2],
<span class=
"s2">\sin
</span>),
</p>
98 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\dur
</span>,
0.125</p>
99 <p class=
"p5">).play;
</p>
100 <p class=
"p6"><br></p>
101 <p class=
"p5">p.stop;
</p>
102 <p class=
"p2"><br></p>
103 <p class=
"p3">The releaseNode and loopNode envelope parameters do not take effect, because they are meaningful only when used in a Synth with a gated EnvGen.
</p>
104 <p class=
"p2"><br></p>
105 <p class=
"p3">When the envelope ends, the stream will hold the final level indefinitely. The
<span class=
"s1">Pif
</span>(
<span class=
"s1">Ptime
</span>(
<span class=
"s1">inf
</span>)
< totalTime,
<span class=
"s1">Env
</span>(...)) trick can make it stop instead.
</p>
106 <p class=
"p2"><br></p>
107 <p class=
"p4">// Use an envelope to pan notes from left to right and back
</p>
108 <p class=
"p4">// Plays one cycle
</p>
110 <p class=
"p5">p =
<span class=
"s1">Pbind
</span>(
</p>
111 <p class=
"p4"><span class=
"s3"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// change to inf: we don't need to know exactly how many events are needed
</p>
112 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\degree
</span>,
<span class=
"s1">Pwhite
</span>(-
4,
11,
<span class=
"s1">inf
</span>),
</p>
113 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\pan
</span>,
<span class=
"s1">Pif
</span>(
<span class=
"s1">Ptime
</span>(
<span class=
"s1">inf
</span>)
<=
4.0,
<span class=
"s1">Env
</span>(#[-
1,
1, -
1], #[
2,
2],
<span class=
"s2">\sin
</span>)),
</p>
114 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\dur
</span>,
0.125</p>
115 <p class=
"p5">).play;
</p>
117 <p class=
"p6"><br></p>
118 <p class=
"p5">p.stop;
</p>
119 <p class=
"p6"><br></p>
120 <p class=
"p4">// To keep looping the envelope, wrap Pif inside Pn
</p>
122 <p class=
"p5">p =
<span class=
"s1">Pbind
</span>(
</p>
123 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\degree
</span>,
<span class=
"s1">Pwhite
</span>(-
4,
11,
<span class=
"s1">inf
</span>),
</p>
124 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\pan
</span>,
<span class=
"s1">Pn
</span>(
<span class=
"s1">Pif
</span>(
<span class=
"s1">Ptime
</span>(
<span class=
"s1">inf
</span>)
<=
4.0,
<span class=
"s1">Env
</span>(#[-
1,
1, -
1], #[
2,
2],
<span class=
"s2">\sin
</span>)),
<span class=
"s1">inf
</span>),
</p>
125 <p class=
"p5"><span class=
"Apple-tab-span"> </span><span class=
"s2">\dur
</span>,
0.125</p>
126 <p class=
"p5">).play;
</p>
128 <p class=
"p6"><br></p>
129 <p class=
"p5">p.stop;
</p>
130 <p class=
"p2"><br></p>
131 <p class=
"p2"><br></p>
132 <p class=
"p9"><span class=
"s3">Previous:
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"PG_06a_Repetition_Contraint_Patterns.html"><span class=
"s6">PG_06a_Repetition_Contraint_Patterns
</span></a></span></p>
133 <p class=
"p9"><span class=
"s3">Next:
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"PG_06c_Composition_of_Patterns.html"><span class=
"s6">PG_06c_Composition_of_Patterns
</span></a></span></p>